#include <stdio.h>
#include <stdlib.h>


int size=0;
struct node{
	int value;
	struct node * next;
	}*list,*rear;
void clearmemory()
{
	while(list!=NULL)
		{
		rear=list;
		list=list->next;
		free(rear);
		}
}


void appendlist(int num)
	{
	//size++;
	struct node *newnode;
	newnode=malloc(sizeof(struct node *));
	if(newnode==NULL)
		{
		printf("ERROR!!!NO MEMORY AVAILABLE");
		clearmemory();
		}
	else
		{
		size++;
		newnode->value=num;
		newnode->next=NULL;
		if(list==NULL)
			list=rear=newnode;
		else
			{
			rear->next=newnode;
			rear=newnode;	
			}
		}
	}
//////////////////////////////////////////////
/////Work on Extend yet to be done i.e.///////
///////i.e.extending a list not number////////
//////////////////////////////////////////////
void insertlist(int pos,int num)
	{
	struct node *cur, *prev, *newnode;
	int i=0;
	if(pos>size+1)
		printf("ERROR!!!!INVALID POSITION");
	else
		{
		newnode=malloc(sizeof(struct node));
		if(newnode==NULL)
			{
			printf("ERROR!!!NO MEMORY AVAILABLE");
			clearmemory();
			}
		else
			{
			size++;
			newnode->value=num;
			newnode->next=NULL;
			if(list==NULL)
				{
				list=newnode;
				}
			else
				{
				for(cur=list;i<pos-1;prev=cur,cur=cur->next,i++);
				if(pos==1)
					{
					newnode->next=list;
					list=newnode;
					}
				else if(pos==size+1)
					rear->next=newnode;				
				else
					{
					newnode->next=cur;
					prev->next=newnode;
					}
				}
			}
		}
	}

void displaylist()
	{
	struct node *temp;
	printf("\n");
	for(temp=list;temp!=NULL;temp=temp->next)
		{
		printf("%d->",temp->value);
		}
	printf("\n");
	}
void removelist(int num)
	{
	struct node *cur, *prev;
	int flag;
	flag=0;
	if(list->value==num)
		{
		cur=list;
		list=list->next;
		free(cur);
		flag=1;
		}
	else
		{
		for(cur=list;cur!=NULL;prev=cur,cur=cur->next)
			{
			if(cur->value==num)
				{
				prev->next=cur->next;
				free(cur);
				size--;
				flag=1;
				break;
				}
			}
			
		}
	if(flag==0)
		printf("ERROR: NUMBER NOT IN LIST!!!!!\n");
	}
int poplist(int pos)
	{
	int element,i;
	struct node *temp, *temp1;
	if(pos<=size && pos>0)
		{
		temp=list;
		if(pos==1)
			{
			element=temp->value;
			list=list->next;			
			free(temp);
			}
		else
			{
			for(i=2;i<pos;i++)
				temp=temp->next;
			temp1=temp->next;
			if(temp1->next==NULL)
				temp->next=NULL;
			else
				temp->next=temp1->next;
			element=temp1->value;
			free(temp1);
			}
		return element;
		}
	else
		{
		element=-1;
		return element;
		printf("ERROR:INVALID POSITION!!!!");
		}
	}

int indexlist(int pos)
	{
	int i=0;
	struct node *temp;
	if(pos<=size)
		{
		temp=list;
		for(i=1;i<=pos;i++)
			temp=temp->next;
		printf("Element at position %d is %d",pos,temp->value);
		return temp->value;
		}
	else
		printf("Error!!!INVALID POSITION");
		return -1;
	}

////////////////////
////Yet to edit/////
////sort & reve/////
////////////////////
void sortlist()
	{
	int i, j;
	struct node *p0, *p1, *p2, *p3;
	for(i = 1; i <size; i++)
		{
		displaylist();
		p0 = NULL;
		p1 = list;
		p2 = list->next;
		p3 = p2->next;
		for(j = 1; j <= (size - i); j++)
			{
			if(p1->value > p2->value)  
				{
				// Adjust the pointers...       
				p1->next = p3;
				p2->next = p1;
				if(p0!=NULL)
					p0->next=p2;
				// Set the head pointer if it was changed...
				if(list == p1)
					list=p2;
				// Progress the pointers
				p0 = p2;
				p2 = p1->next;
				if(p3->next!=NULL)
					p3=p3->next;
				else
					p3=NULL;
				}
			else
				{
				// Nothing to swap, just progress the pointers...
				p0 = p1;
				p1 = p2;
				p2 = p3;
				if(p3->next!=NULL)
					p3=p3->next;
				else
					p3=NULL;
				}
			}
		}
	}


int reverselist()
	{

	}

int count(int num)
	{
	struct node *temp;
	int ctr;
	ctr=0;
	for(temp=list;temp!=NULL;temp=temp->next)
		{
		if(temp->value==num)
			ctr++;
		}
	return ctr;
	}
/////////////////////////////
///function yet to be made///
/////////////////////////////
void help()
	{
	
	}
	

int main(void)
	{
	int pos=0;
	int choice=1;
	int i=0;
	int *list1;
	while(choice)
		{
		printf("1)Append\n2)Extend\n3)Insert\n4)Remove\n5)Poplastelement\n6)Pop\n7)Index\n8)Count\n9)Sort\n10)Reverse\n11)Help\n0)Exit\nYour Choice ");
		scanf(" %d",&choice);
		switch(choice)
			{
			case 1:
				{
				printf("Enter number to append");
				scanf("%d",&pos);//Actually its not position(pos) but a number
				appendlist(pos);
				break;
				}
			case 2:
				{
				printf("Enter no. of elements you would like to Extend in the List");
				scanf("%d",&pos);//Total numbers to be extended
					while(pos!=0)//Its a number not position
						{
						printf("Enter the number");
						scanf(" %d",&i);//Numbers to be extended
						appendlist(i);//Its a number
						pos--;
						}
				break;
				}
			case 3:
				{
				printf("Enter Position");
				scanf(" %d",&pos);
				printf("Enter Number");
				scanf(" %d",&i);//Number
				insertlist(pos,i);
				break;
				}
			case 4:
				{
				printf("Enter number to be removed");
				scanf("%d",&pos);	//pos is a number	
				removelist(pos);
				break;
				}
			case 5:
				{
				pos=poplist(size);//pos represents element poped not position
				printf("Element Removed %d",pos);
				break;
				}
			case 6:
				{
				printf("Enter position to be poped out");
				scanf("%d",&pos);//this pos is for position
				pos=poplist(pos);//pos on l.h.s. represents element poped not position
				printf("Element Removed %d",pos);
				break;
				}
			case 7:
				{
				printf("Enter Index: ");
				scanf("%d",&pos);
				pos=indexlist(pos);	//here pos has the element
				break;
				}
			case 8:
				{
				printf("Enter Integer");
				scanf("%d",&pos);	//here pos is value whose count is to be found
				pos=count(pos);		//here pos on l.h.s. has the count
				break;
				}
			case 9:
				{
				sortlist();
				break;
				}
			case 10:
				{
				reverselist();
				break;
				}
			case 11:
				{
				help();
				break;
				}
			default:
				{
				clearmemory();
				break;
				}
			}
		displaylist();
		}
	return 0;
	}	
